<template>
  <demo-content :title="title">
    <p></p>
    <canvas ref="canvasRef" width="600" height="400"></canvas>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";

const title = "重力模拟";
// 指定组件上的属性
defineOptions({ title });

const canvasRef = ref<HTMLCanvasElement>();
function randomColor() {
  const s = "0123456789ABCDEF";
  let c = "#";
  for (let i = 0; i < 6; i++) {
    c += s[Math.ceil(Math.random() * 15)];
  }
  return c;
}
class Ball {
  canvas: HTMLCanvasElement;
  ctx: CanvasRenderingContext2D;
  x: number;
  y: number;
  r: number;
  color: string;
  vx: number;
  vy: number;
  // 加速度
  a: number;
  // 速度损耗
  f: number;
  constructor(
    canvas: HTMLCanvasElement,
    x: number,
    y: number,
    r: number,
    color: string
  ) {
    this.canvas = canvas;
    this.ctx = canvas.getContext("2d")!;
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = color;
    this.vx = Math.random() * 30 - 15;
    this.vy = 0;
    this.a = 5;
    this.f = 0.95;
  }
  draw() {
    if (Math.abs(this.vx) <= 0.1 && Math.abs(this.vy) <= 0.1) {
      return;
    }
    console.log("vx,vy: ", this.vx, this.vy);
    if (this.vy < 0 && this.vy + this.a > 0) {
      this.vy = 0;
    } else {
      this.vy += this.a;
    }
    let tx = this.x + this.vx;
    let ty = this.y + this.vy;
    if (tx - this.r <= 0) {
      tx = this.r;
      this.vx = -this.vx;
      this.vx *= this.f;
    } else if (tx + this.r >= this.canvas.width) {
      tx = this.canvas.width - this.r;
      this.vx = -this.vx;
      this.vx *= this.f;
    }
    if (ty + this.r >= this.canvas.height) {
      ty = this.canvas.height - this.r;
      this.vy = -this.vy;
      this.vy *= this.f;
      this.vx *= 1 - (1 - this.f) / 3;
    }
    this.x = tx;
    this.y = ty;
    this.ctx.save();
    this.ctx.beginPath();
    this.ctx.fillStyle = this.color;
    this.ctx.arc(tx, ty, this.r, 0, Math.PI * 2);
    this.ctx.fill();
    this.ctx.restore();
  }
}
onMounted(() => {
  const canvas = canvasRef.value!;
  const ctx = canvas.getContext("2d")!;
  ctx.save();
  ctx.fillStyle = "#000000";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.restore();
  const balls: Ball[] = [];
  balls.push(new Ball(canvas, canvas.width / 2, 10, 10, "orange"));
  function draw() {
    ctx.save();
    ctx.fillStyle = "#00000080";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.restore();
    balls.forEach((ball) => {
      ball.draw();
    });
    requestAnimationFrame(draw);
  }
  draw();
});
</script>

<style src="./default.css" scoped></style>
